import {
  h,
  render,
  nextTick,
  App,
  ComponentInternalInstance,
  ComponentPublicInstance,
} from "vue";
import { DomUtil } from "../../utils";
import TooltipConstructor from "./tooltip.vue";
import { TooltipAttr, TooltipPosition } from "./tooltip.type";
const arrowSize = 0;
const Tooltip = {
  install(app: App) {
    app.directive("tooltip", {
      mounted(el, binding) {
        let component: (ComponentPublicInstance & TooltipAttr) | null = null;
        const position: string = binding.arg || "top";
        el.addEventListener("mouseover", () => {
          if (component) return;
          const box = DomUtil.getElBox(el);
          const fixedParent = DomUtil.findTargetParent(
            el,
            (el: HTMLElement) => {
              return DomUtil.getStyle(el, "position") === "fixed";
            }
          );
          let container: HTMLDivElement | null = document.createElement("div");
          const vnode = h(TooltipConstructor, {
            onDestroy() {
              console.log("tooltip destroy");
              render(null, container as HTMLDivElement);
              container = null;
            },
          });
          render(vnode, container);
          document.body.appendChild(container.firstElementChild as Element);
          component = (vnode.component as ComponentInternalInstance)
            .proxy as ComponentPublicInstance & TooltipAttr;
          component.position = position as TooltipPosition;
          component.message = binding.value;
          component.isFixed = !!fixedParent;
          component.show = true;
          nextTick(() => {
            if (!component) return;
            const toolTipWidth = component.$el.offsetWidth;
            const toolTipHeight = component.$el.offsetHeight;
            const topBottomLeft = box.left + (box.width - toolTipWidth) / 2;
            const leftRightTop = box.top + (box.height - toolTipHeight) / 2;
            let left, top;
            switch (position) {
              case "top":
                left = topBottomLeft;
                top = box.top - (toolTipHeight - arrowSize / 2);
                break;
              case "start":
                left = box.left - (toolTipWidth - arrowSize / 2);
                top = leftRightTop;
                break;
              case "bottom":
                left = topBottomLeft;
                top = box.top + box.height - arrowSize / 2;
                break;
              case "end":
                left = box.left + box.width - arrowSize / 2;
                top = leftRightTop;
            }
            if (left === undefined) {
              console.error("tooltip的position值错误");
              return;
            }
            component.left = left;
            component.top = top || 0;
          });
        });
        el.addEventListener("mouseout", () => {
          if (!component) return;
          component.show = false;
          component = null;
        });
      },
    });
  },
};
export default Tooltip;
